<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/6/8 0008
 * Time: 15:37
 */

namespace app\api\controller\v1\cleaner;


use app\api\controller\v1\Cleaner;
use app\currency\service\CitiesService;
use app\currency\service\CleanerService;
use app\currency\service\WechatTemplateService;
use think\Db;
use think\exception\HttpResponseException;

class Order extends Cleaner
{
    /**
     * 订单列表
     * 筛选方式：全部（0）、待接单（1）、进行中（2）、已完结（3）
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function index()
    {

        $status = (int)$this->request->get('status',0);
        in_array($status,[0,1,2,3]) || $status = 0;
        $where = [];
        if($status === 1)
        {
            $this->orderTaking();
        } else {
            $where[] = ['cid','eq',$this->cid];
            if($status === 2)
            {
                $where[] = ['status','in',['2','3']];
            }
            elseif ($status === 3)
            {
                $where[] = ['status','eq','4'];
            }
        }
        $list = $this->_query('CleanOrder')
            ->where($where)
            ->order('create_at desc')
            ->page(true,false,false,10);
        $list['unread_num'] = Db::name('CleanOrder')->where([
            ['status','eq','4'],
            ['read_status','eq','0'],
            ['cid','eq',$this->cid]
        ])->count();
        $list['hand_num'] = Db::name('CleanOrder')->where([
            ['status','in',['2','3']],
            ['cid','eq',$this->cid]
        ])->count();
        $list['accept_num'] = CleanerService::getOrderTaking($this->cid);
        $this->success('查询订单列表成功！',$list);
    }
    protected function _index_page_filter(array &$data)
    {
        $mids = array_unique(array_column($data,'mid'));
        $member_list = Db::name('Member')->whereIn('id',$mids)->select();
        foreach ($data as &$item) {
            $item['address_txt'] = CitiesService::getAddressText($item['cities_id'],'string');
            $item['member'] = [];
            foreach ($member_list as $member) if($item['mid'] == $member['id']) {
                $item['member'] = $member;
            }
        }
    }
    /**
     * 查询待接单订单
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    private function orderTaking()
    {
        $unread_num = Db::name('CleanOrder')->where([
            ['status','eq','4'],
            ['read_status','eq','0'],
            ['cid','eq',$this->cid]
        ])->count();
        $hand_num = Db::name('CleanOrder')->where([
            ['status','in',['2','3']],
            ['cid','eq',$this->cid]
        ])->count();
        $accept_num = CleanerService::getOrderTaking($this->cid);
        if($this->cleaner->work_state == '0' || $this->cleaner->auth_state == '0')
        {
            $this->success('获取订单列表成功！',[
                'page' => ['limit' => 10,'total' => 0,'pages' => 1,'current' => 1],
                'list' => [],
                'unread_num' => $unread_num,
                'hand_num' => $hand_num,
                'accept_num' => $accept_num
            ]);
        }
        $db = $this->_query('CleanOrder');
        //计算订单时间是否更自己工作时间冲突
        $getAvailableTimeSlot = CleanerService::getAvailableTimeSlot($this->cid);
        empty($getAvailableTimeSlot) && $this->success('获取订单列表成功！',[
            'page' => ['limit' => 10,'total' => 0,'pages' => 1,'current' => 1],
            'list' => [],
            'unread_num' => $unread_num,
            'hand_num' => $hand_num,
            'accept_num' => $accept_num
        ]);
        $whereOr = [];
        foreach ($getAvailableTimeSlot as $key => $item) {
            $week = $item['week'];
            if($week == '7') $week = '0';
            $week++;
            $whereOr[$key][] = ['time_slot','in',$item['time_slot']];
            $whereOr[$key][] = ['','exp',Db::raw("DAYOFWEEK(service_date) = {$week}")];
        }
        $where = [];
        $where[] = ['status','eq','1'];
        //计算非指定或者指定自己的
//        $where[] = ['appoint_cid','in',['0',$this->cid]];
        //排除已经被拉黑的
        $member_blacklist = Db::name('MemberBlacklist')
            ->where('cid','eq',$this->cid)->select();
        $blacklist_mids = array_unique(array_column($member_blacklist,'mid'));
        if(!empty($blacklist_mids))
        {
            $where[] = ['mid','not in',$blacklist_mids];
        }
        $list = $db->where($where)
            ->where(function($query) use($whereOr){
                $query->whereOr($whereOr);
            })
            ->where(function ($query){
                $query->whereOr([
                    [
                        ['appoint_cid','eq',$this->cid],
                        ['cleaner_cancel_status','eq','0']
                    ],
                    [
                        ['appoint_cid','eq','0']
                    ],
                    [
                        ['appoint_cid','not in',['0',$this->cid]],
                        ['cleaner_cancel_status','eq','1']
                    ]
                ]);
            })
            ->page(true,false,false,10);
        $list['unread_num'] = $unread_num;
        $list['hand_num'] = $hand_num;
        $list['accept_num'] = $accept_num;
        $this->success('查询订单列表成功！',$list);
    }

    /**
     * 订单详情
     * @param $id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function read($id)
    {
        $order = Db::name('CleanOrder')
            ->where([['order_no','eq',$id],['cid','eq',$this->cid]])->find();
        if(!empty($order))
        {
            if($order['status'] == '4')
            {
                Db::name('CleanOrder')->where('order_no','eq',$id)->setField('read_status','1');
            }

            $order['address_txt'] = CitiesService::getAddressText($order['cities_id'],'string');
            $order['member'] = Db::name('Member')->where('id','eq',$order['mid'])->find();
        }
        $this->success('获取订单详情成功！',$order);
    }

    /**
     * 更新订单： 接单receipt、设置服务开启service_start、设置服务结束service_end、补全订单complete
     * 需要做的权限验证：是否有权限更新此订单
     */
    public function save()
    {
        $data = $this->_input([
            'action' => $this->request->post('action'),
            'order_no' => $this->request->post('order_no'),
            'service_duration' => $this->request->post('service_duration'),
            'house_type' => $this->request->post('house_type')
        ],[
            'action' => 'require|in:receipt,service_start,service_end,complete,read',
            'order_no' => 'require|number|length:12',
            'service_duration' => 'requireIf:action,complete|number',
            'house_type' => 'requireIf:action,complete',
        ],[
            'action.require' => '请选择操作类型！',
            'action.in' => '不被支持的操作！',
            'order_no.require' => '请输入订单号！',
            'order_no.number' => '订单号格式错误！',
            'order_no.length' => '订单号长度错误！'
        ]);
        $where = [['order_no','eq',$data['order_no']]];
        if($data['action'] != 'receipt')
        {
            //验证订单归属问题
            $where[] = ['cid','eq',$this->cid];
        }
        $order = Db::name('CleanOrder')->where($where)->find();
        empty($order) && $this->error('查询订单信息失败！');
        switch ($data['action'])
        {
            case 'receipt':
                //接单
                //判断权限，是否能接此订单
                //实名认证判定
                if($this->cleaner->auth_state != '1')
                {
                    $this->error('您还未实名认证！');
                }
                //拉黑判定
                if(Db::name('MemberBlacklist')->where([['mid','eq',$order['mid']],['cid','eq',$this->cid]])->count() > 0)
                {
                    $this->error('你已被用户拉入黑名单，无法接单！');
                }
                //避免重复接单
                if(Db::name('CleanOrder')
                        ->where([
                            ['cid','eq',$this->cid],
                            ['service_date','eq',$order['service_date']],
                            ['time_slot','eq',$order['time_slot']],
                            ['status','eq','2']
                        ])->count() > 0)
                {
                    $this->error('接单冲突！');
                }
                //工作时间判断
                $getAvailableTimeSlot = CleanerService::getAvailableTimeSlot($this->cid);
                empty($getAvailableTimeSlot) && $this->error('工作状态冲突！');
                $week = date('w',strtotime($order['service_date']));
                if($week == '0') $week = '7';
                $time_slot = '';
                foreach ($getAvailableTimeSlot as $item) {
                    if($week === $item['week'])
                    {
                        $time_slot = $item['time_slot'];
                        break;
                    }
                }
                if(!in_array($order['time_slot'],array_filter(explode(',',$time_slot))))
                {
                    $this->error('工作时间冲突！');
                }
                $res = Db::name('CleanOrder')->where($where)->update(['cid' => $this->cid,'status' => '2']);
                if($res)
                {
                    //插入模板消息
                    $openid = Db::name('Member')->where('id',$order['mid'])->value('openid');
                    WechatTemplateService::sendOrderReceive($openid,$this->cleaner->name ?: '未设置姓名',$this->cleaner->phone);
                    $this->success('接单成功！');
                } else {
                    $this->error('接单失败！');
                }

                break;
            case 'service_start':
                if($order['is_no_complete'] == '1')
                {
                    $this->error('请完善订单！');
                }
                //设置服务开启
                $dateTime = date('Y-m-d H:i:s');
                $res = Db::name('CleanOrder')->where($where)->update([
                    'service_status' => 1,
                    'service_start_at' => $dateTime
                ]);
                if($res !== false)
                {
                    //插入模板消息
                    $openid = Db::name('Member')->where('id',$order['mid'])->value('openid');
                    WechatTemplateService::sendOrderServiceStart($openid,$order['order_no'],$dateTime);
                    $this->success('设置服务开始成功！');
                } else {
                    $this->error('设置服务开始失败！');
                }
                break;
            case 'service_end':
                if($order['is_no_complete'] == '1')
                {
                    $this->error('请完善订单！');
                }
                //设置服务结束
                $dateTime = date('Y-m-d H:i:s');
                $res = Db::name('CleanOrder')->where($where)->update([
                    'service_status' => 2,
                    'service_end_at' => $dateTime,
                    'status' => '3'
                ]);
                if($res !== false)
                {
                    //插入模板消息
                    $openid = Db::name('Member')->where('id',$order['mid'])->value('openid');
                    WechatTemplateService::sendOrderServiceEnd($openid, $order['order_no'], $order['service_start_at'], $dateTime);
                    $this->success('设置服务结束成功！');
                } else {
                    $this->error('设置服务结束失败！');
                }
                break;
            case 'read':
                //设置已读
                $where[] = ['status','eq',4];
                Db::name('CleanOrder')->where($where)->update([
                    'read_status' => 1
                ]);
                $this->success('操作成功！');
                break;
            case 'complete':
                //补全订单
                if($order['is_no_complete'] != '1')
                {
                    $this->error('此订单已补全！');
                }
                $unit_price = sysconf('service_unit_price') ?: 0;
                $total_price = $unit_price*$data['service_duration'];
                try {
                    Db::transaction(function()use($order,$data,$where,$total_price){
                        //修改订单状态
                        Db::name('CleanOrder')->where($where)->update([
                            'total_price' => $total_price,
                            'actual_amount' => $total_price,
                            'service_duration' => $data['service_duration'],
                            'is_no_complete' => '0'
                        ]);
                        //修改地址表
                        Db::name('Cities')
                            ->where('id','eq',$order['cities_id'])
                            ->update(['service_duration' => $data['service_duration'],'house_type' => $data['house_type']]);
                    });
                    $this->success('补全订单成功！', '');
                } catch (HttpResponseException $exception) {
                    throw $exception;
                } catch (\Exception $e) {
                    $this->error("补全订单失败，请稍候再试！{$e->getMessage()}");
                }
                break;
        }
    }
    public function delete($id)
    {
        $where = [['order_no','eq',$id],['status','eq','1'],['cleaner_cancel_status','eq','0'],['appoint_cid','eq',$this->cid]];
        Db::name('CleanOrder')->where($where)->update([
            'cleaner_cancel_status' => '1'
        ]);
        $this->success('success');
    }
}